<template>
  <m-modal
    v-model="visible"
    title="属性"
    class="v-attribute-muti-select"
    :confirmDisabled="isRequired && this.selectInfo.rightSelects.length <= 0"
    mask
    :center="true"
    @ok="handleOk"
    @cancel="handleCancel">
    <m-attr-tip type="checkbox"/>
    <div class="g-flex g-pd-20" >
      <div style="width:294px;border:1px solid #bbb" class="g-flex-0" >
        <a-tabs
          v-model="selectInfo.curTab"
          class="_tree-content"
          type="card"
        >
          <a-tab-pane key="tree" tab="树">
            <div class="g-pd-lr-20 g-pd-b-20 g-pd-t-10"  style="height:400px;">
              <a-select
                show-search
                placeholder="搜索"
                option-filter-prop="children"
                style="width: 100%;margin-bottom:10px"
                size="small"
                @change="handleSelectChange"
                @search="handleSelectSearch"
              >
                <a-icon slot="suffixIcon" type="search" />
                <a-select-option v-for="(item,index) in selectOptions" :key="index"  :value="item.id" :title="item.label">
                  {{item.label}}
                </a-select-option>
              </a-select>
              <div style="height:350px;overflow:auto">
                <m-select-tree
                  :treeData="treeData"
                  @select="handleTreeSelect"
                />
              </div>
            </div>
          </a-tab-pane>
          <a-tab-pane key="list" tab="列表">
            <div class="g-pd-lr-20 g-pd-b-20 g-pd-t-10" style="height:400px;">
              <a-select
                show-search
                placeholder="搜索"
                option-filter-prop="children"
                style="width: 100%;margin-bottom:10px"
                size="small"
                @change="handleSelectChange"
                @search="handleSelectSearch"
              >
                <a-icon slot="suffixIcon" type="search" />
                <a-select-option v-for="(item,index) in selectOptions" :key="index"  :value="item.id" :title="item.label">
                  {{item.label}}
                </a-select-option>
              </a-select>
              <div style="height:350px;overflow:auto">
                <m-list :list="list" @select="handleListSelect"/>
              </div>
            </div>
          </a-tab-pane>
        </a-tabs>

      </div>
      <div style="width:60px" class="g-flex-1 g-flex-center g-fd-c">
        <a-button type="primary" @click="toRight">
          <img src='statics/icons/app/arrowrightwhite.png'/>
        </a-button>
        <a-button type="primary" class="g-m-t-20" @click="handleFresh">
          <img src='statics/icons/app/iconrefurbish.png'/>
        </a-button>
      </div>
      <div style="height:555px;width:294px;border:1px solid #bbb" class="g-flex-0">
        <div class="_header-bar g-pd-l-8">
          已选择数量：<span class="g-c-blue-mid g-bolder ">{{selectInfo.rightSelects.length}}</span>
        </div>
        <div class="_bar-content">
          <div
            v-for="item in selectInfo.rightSelects"
            :key="item.value"
            class="_row g-flex g-ai-c g-pd-lr-10"
          >
            <img :src="item.iconPath" :alt="item.iconPath" style="width: 16px;height: 16px;" class="g-flex-0"/>
            <div class="g-flex-1 g-m-lr-10">

              {{item.displayTitle || '---'}}
            </div>
            <img src="statics/icons/app/icondelete2.png" class="g-pointer g-flex-0" style="height:12px;width:12px" @click="handleRemove(item)" />
          </div>
        </div>

      </div>

    </div>

  </m-modal>
</template>
<script>
import { Portal } from 'src/components/common/Portal.vue';
import { debounce } from 'lodash';
import { treeForEach, initTree } from 'src/util/common';
import Modal from 'src/components/common/CustomModal';
import AttrTip from '../comps/AttrTip';
import SelectTree from '../comps/SelectTree';
import SelectList from '../comps/SelectList';
import { ModelPropertyMutator } from '@/api/generator/model-property-modify';
import { graphHelper } from 'src/api/GraphHelper';

const comp = {
  name: 'comp-select-muti',
  components: {
    'm-modal': Modal,
    'm-attr-tip': AttrTip,
    'm-select-tree': SelectTree,
    'm-list': SelectList,
  },
  props: {
    type: String,
    currentIds: Array,
    filterCondtion: String,
    propertyKey: [Object, String],
    selectedElement: [Object, String],
    isNodeSelectable: Function,
    isRequired: {
      type: Boolean,
      default: false
    }
  },
  data() {
    const treeData = this.formatTreeData(this.getTreeData());
    if (this.filterCondtion) {
      this.filterDisabled(treeData);
    }
    console.log('treeData', treeData);
    return {
      visible: false,
      treeData,
      list: this.getList(treeData),
      selectInfo: {
        curTab: 'tree',
        rightSelects: [],
      },
      selectOptions: [],
      selectOptionsCache: []
    };
  },
  mounted() {
    this.visible = true;
    this.selectInfo.rightSelects = this.getExistItems();
  },

  methods: {
    getExistItems() {
      const existItems = [];
      this.currentIds.forEach(id => {
        const item = this.list.find(it => it.id === id);
        if (item) {
          item.disabled = true;
          item.selected = true;
          existItems.push(item);
        }        
      });
      return existItems;
    },

    handleOk() {
      this.visible = false;
      console.log('ok');
      this.$emit('sure', this.selectInfo.rightSelects);
    },
    handleCancel() {
      this.visible = false;
      this.$emit('close');
    },

    getTreeData(){
      return [app.sysmlModel];
    },
    formatTreeData(data) {
      const tree = initTree(data, {
        labelKey: '1',
        valueKey: 'id',
        clean: false,
        keepParent: true,
        cutomFn: (node, source) => {
          //// node.scopedSlots = { title: 'default' };
          //// node.iconPath = source.iconPath;
          //// node.value = source.value;
          node.graphNode = source;
          node.getTypeName = function(){
            return node.graphNode.getTypeName();
          };
          Object.defineProperty(node, 'displayTitle', {
            get(){
              return source.displayTitle;
            }
          });
          Object.defineProperty(node, 'iconPath', {
            get(){
              return source.iconPath;
            }
          });
          //// node.displayTitle = source.displayTitle;          
          if (this.isNodeSelectable) {
            node.disabled = !this.isNodeSelectable(source);
          } else {
            node.disabled = !ModelPropertyMutator.isNodeSelectable(
              this.selectedElement,
              this.propertyKey,
              source,
              this.filterCondtion
            );
          }
          //// node.disabled = !ModelPropertyMutator.isNodeSelectable(
          ////   this.selectedElement,
          ////   this.propertyKey,
          ////   source.model,
          ////   this.filterCondtion
          //// );
          node.selected = this.currentIds && this.currentIds.includes(source.value);
        }
      });
      //// const tree = initTree(data, {
      ////   labelKey: 'displayTitle',
      ////   valueKey: 'value',
      ////   clean: false,
      ////   cutomFn: (node, source) => {
      ////     node.iconPath = source.iconPath;
      ////     node.value = source.value;
      ////     node.graphNode = source;
      ////     node.displayTitle = source.displayTitle;

      ////     if (this.isNodeSelectable) {
      ////       node.disabled = !this.isNodeSelectable(source);
      ////     } else {
      ////       node.disabled = !ModelPropertyMutator.isNodeSelectable(
      ////         this.selectedElement,
      ////         this.propertyKey,
      ////         source.model,
      ////         this.filterCondtion
      ////       );
      ////     }

      ////     node.selected = this.currentIds && this.currentIds.includes(source.value);
      ////   }
      //// });
      console.log("muti-tree", tree);
      return tree;
    },
    isAllDisabled(node) {
      if (!node.disabled) return false;
      let allDisabled = true;
      node.children &&
				treeForEach(node.children, (node) => {
				  if (!node.disabled) {
				    allDisabled = false;
				    return false;
				  }
				});
      return allDisabled;
    },
    filterDisabled(treeData) {
      treeForEach(treeData, (node, parent) => {
        if (node.children) {
          for (let i = 0; i < node.children.length; i++) {
            if (this.isAllDisabled(node.children[i])) {
              node.children.splice(i, 1);
              i--;
            }
          }
        }
        return treeData;
      });
    },
    getList(treeData) {
      const list = [];
      treeForEach(treeData, (node) => {
        list.push(node);
        node.selected = false;
      });
      return list;
    },
    handleTreeSelect(data, selected) { //// 传入selected时，元素一定选中
      //// 点击时触发
      if (!this.isRequired) {
        data.selected = !data.selected;
      } else {
        data.selected = true;
      }

      if (selected) {
        data.selected = true;
      }

      if (this.type === 'Requirement') {
        this.childrenSelect(data.selected, data);
      }
    },
    handleListSelect(data) {
      if (!this.isRequired) {
        data.selected = !data.selected;
      } else {
        data.selected = true;
      }
      if (this.type === 'Requirement') {
        this.childrenSelect(data.selected, data);
      }
    },

    //// 同时改变子节点选择状态
    childrenSelect(select, data) {
      treeForEach([data], (node) => {
        node.selected = select;
      });
    },

    getSelectedItem() {
      return this.list.filter(data => data.selected);
    },
    insertRight(items) {
      if (this.type === 'Requirement') {
        const idObj = {};
        const arr = [];
        items.forEach(item => {
          idObj[item.id] = true;
          item.disabled = true;
          arr.push(item);
        });
        const filteredArr = this.selectInfo.rightSelects.filter(item => !idObj[item.id]);
        this.selectInfo.rightSelects = filteredArr.concat(arr);
      } else {
        items.forEach((item) => {
          if (!this.selectInfo.rightSelects.find((i) => i.value === item.value)) {
            this.selectInfo.rightSelects.push(item);
            item.disabled = true;
          }
        });
      }
    },
    toRight() {
      //// if (this.selectInfo.curTab === 'tree') {
      this.insertRight(this.getSelectedItem());
      //// } else {
      ////   this.insertRight(this.selectInfo.listSelectItems);
      //// }
    },
    handleFresh() {
      this.selectInfo.rightSelects.forEach(i => i.disabled = false);
      this.selectInfo.rightSelects = [];
    },
    handleRemove(item) {
      if (this.type === 'Requirement') {
        const removeIdObj = {};
        treeForEach([item], (node) => {
          removeIdObj[node.id] = true;
          node.disabled = false;
          item.selected = false;
        });
        this.selectInfo.rightSelects = this.selectInfo.rightSelects.filter(
          (i) => !removeIdObj[i.id]
        );
      } else {
        this.selectInfo.rightSelects = this.selectInfo.rightSelects.filter(
          (i) => i !== item
        );
        item.disabled = false;
        item.selected = false;
      }
    },
    handleSelectSearch: debounce(function(query){
      console.log(query);
      const flatData = [];
      if (query === '' ) {
        this.selectOptions = [];
        return flatData;
      };
      query = query.toLowerCase();
      treeForEach(this.treeData, i => {
        const name = !i.disabled && i.graphNode.model && ( i.graphNode.model.name ||  i.graphNode.model.body ||  i.graphNode.title);
        if (name && name.toLowerCase().includes(query)) {

          flatData.push({ label: i.graphNode.title, id: i.graphNode.id });
        };
      });
      this.selectOptions = flatData;

    }, 200),
    handleSelectChange(id){
      console.log(id);
      const result = this.list.find(it => it.id === id);
      console.log('this.selectOptionsCache', this.selectOptionsCache);
      this.selectOptionsCache.forEach(id => {
        this.list.find(it => it.id === id).selected = false;
      });
      this.selectOptionsCache = [];
      this.selectOptionsCache.push(id);
      this.handleTreeSelect(result, true);
      //// result.selected = true;
      this.expandParent(result);

      //// const graphNode = id && graphHelper.getGraphNodeById(id, app.activeProjectId);
      //// if (graphNode) {
      ////   this.handleSelect(graphNode);
      //// }
      this.$nextTick(() => {
        let wrapperClass =  this.selectInfo.curTab === 'tree' ? '.v-select-tree' : '.v-select-list';
       
        const dom = document.querySelector(wrapperClass + ' #v' + result.id); 
        if (dom){
          dom.scrollIntoView({ behavior: "smooth", block: "center", inline: "nearest" });
        }
      });

    },
    expandParent(node){
      if (node.parent){
        node.parent.expand = true;
        this.expandParent(node.parent);
      }

    }
  },
};
export default comp;
export const selectMutiple = new Portal(comp, { single: true });
export const portal = selectMutiple;
</script>
<style lang="scss" scoped>
.v-attribute-muti-select {
	._header-bar {
    background: #E1F4FF;
    border-bottom: 1px solid rgb(187, 187, 187);;
		height: 28px;
		line-height: 28px;
	}
	._bar-content {
		overflow-y: auto;
		height: calc(100% - 35px);
	}
	._tree-content {
		overflow-y: auto;
		padding-bottom: 125px;
	}
	.ant-tabs-card-content {
		overflow-y: auto;
	}
}
</style>
<style lang="scss">
._tree-content{
  /deep/ .ant-tabs-bar{
    border:0;
    border-bottom: 1px solid #B1CEE2;
  }
  /deep/ .ant-tabs-tab{
    padding:0 8px !important;
  }
}
</style>
